package domain

import (
	"errors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"shimmer/neusoft_club_backend/services"
	"time"
)

const (
	UserContextName = "user_context_name"
	UserSessionID   = "user_domain.id"
)
const (
	UserFieldActors = "Actors"
	UserFieldAvatar = "Avatar"
)

type UserGender int32

const (
	UserGenderNone UserGender = iota
	UserGenderMale
	UserGenderFemale
)

type User struct {
	ID        int64          `json:"id"`
	Nickname  string         `json:"nickname" gorm:"not null;unique"`
	Name      *string        `json:"name" gorm:"type:varchar(255)"`
	AvatarID  *int64         `json:"-"`
	Gender    UserGender     `json:"gender"`
	Birthday  *time.Time     `json:"birthday"`
	Email     *string        `json:"email" gorm:"type:varchar(255)"`
	QQ        *string        `json:"qq" gorm:"type:varchar(255)"`
	Wechat    *string        `json:"wechat" gorm:"type:varchar(255)"`
	Comment   *string        `json:"comment"`
	CreatedAt time.Time      `json:"created_at" `
	UpdatedAt time.Time      `json:"updated_at" `
	DeletedAt gorm.DeletedAt `gorm:"index"`
	Actors    []UserActor    `json:"actors"`
	Avatar    *Assets        `json:"avatar" gorm:"foreignKey:AvatarID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}
type UserDTO struct {
	ID        int64          `json:"id"`
	Nickname  string         `json:"nickname" gorm:"not null;unique"`
	Name      *string        `json:"name" gorm:"type:varchar(255)"`
	AvatarID  *int64         `json:"-"`
	Gender    UserGender     `json:"gender"`
	Birthday  *time.Time     `json:"birthday"`
	Email     *string        `json:"email" gorm:"type:varchar(255)"`
	QQ        *string        `json:"qq" gorm:"type:varchar(255)"`
	Wechat    *string        `json:"wechat" gorm:"type:varchar(255)"`
	Comment   *string        `json:"comment"`
	CreatedAt time.Time      `json:"created_at" `
	UpdatedAt time.Time      `json:"updated_at" `
	DeletedAt time.Time      `gorm:"index"`
	Actors    []UserActorDTO `json:"actors"`
	Avatar    *AssetsDTO     `json:"avatar" gorm:"foreignKey:AvatarID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}

func GetUserFromContext(c *gin.Context) (*User, error) {
	userInterface, exist := c.Get(UserContextName)
	if !exist {
		return nil, errors.New("not found user in context")
	}
	user, ok := userInterface.(*User)

	if !ok {
		return nil, errors.New("convert interface to user interface failed")
	}
	return user, nil
}

func GetUserFromSession(session sessions.Session) (user *User, err error) {
	userID, ok := session.Get(UserSessionID).(int64)
	if !ok {
		return nil, nil
	}
	user = &User{ID: userID}
	err = services.DBEngine.Find(user).Error
	if err != nil {
		return nil, err
	}
	return
}
